@@ -8,7 +8,6 @@ import shortuuid  | 
            ||
| 8 | 8 | 
                from curtail_uuid import CurtailUUID  | 
            
| 9 | 9 | 
                from django.conf import settings  | 
            
| 10 | 10 | 
                from django.contrib.auth.hashers import check_password  | 
            
| 11 | 
                -from django.core.files.storage import default_storage  | 
            |
| 12 | 11 | 
                from django.db import transaction  | 
            
| 13 | 12 | 
                from isoweek import Week  | 
            
| 14 | 13 | 
                from logit import logit  | 
            
                @@ -29,6 +28,7 @@ from utils.redis.rkeys import GROUP_LAST_PHOTO_PK, TODAY_INCOME, TODAY_UPLOAD_PH  | 
            ||
| 29 | 28 | 
                from utils.redis.rorder import set_lensman_order_record  | 
            
| 30 | 29 | 
                from utils.redis.rprice import get_lensman_price_fixed, set_lensman_price_fixed  | 
            
| 31 | 30 | 
                from utils.redis.rprofile import set_profile_info  | 
            
| 31 | 
                +from utils.storage_utils import file_save  | 
            |
| 32 | 32 | 
                from utils.thumbnail_utils import make_thumbnail  | 
            
| 33 | 33 | 
                from utils.watermark_utils import watermark_wrap  | 
            
| 34 | 34 | 
                 | 
            
                @@ -178,36 +178,10 @@ def lensman_photo_upload_api(request):  | 
            ||
| 178 | 178 | 
                 | 
            
| 179 | 179 | 
                group_id = group.group_id  | 
            
| 180 | 180 | 
                 | 
            
| 181 | 
                - # # 判断 group_id/user_id 的群组用户是否存在,如果不存在,则直接创建  | 
            |
| 182 | 
                - # group_user_current_id = -1  | 
            |
| 183 | 
                -    # group_user, group_user_created = GroupUserInfo.objects.get_or_create(group_id=group_id, user_id=user_id, defaults={
               | 
            |
| 184 | 
                - # 'current_id': group_user_current_id, # 通过扫描 session_id 二维码进群的用户,默认可以查看该群组所有照片  | 
            |
| 185 | 
                - # 'nickname': nickname or user.final_nickname,  | 
            |
| 186 | 
                - # 'avatar': user.avatar,  | 
            |
| 187 | 
                - # 'admin': group_created,  | 
            |
| 188 | 
                - # 'user_status': GroupUserInfo.PASSED,  | 
            |
| 189 | 
                - # 'passed_at': tc.utc_datetime(),  | 
            |
| 190 | 
                - # })  | 
            |
| 191 | 
                - # if not group_user_created:  | 
            |
| 192 | 
                - # group_user.current_id = group_user_current_id  | 
            |
| 193 | 
                - # group_user.user_status = GroupUserInfo.PASSED  | 
            |
| 194 | 
                - # group_user.save()  | 
            |
| 195 | 
                - #  | 
            |
| 196 | 
                - # # Redis 群组用户数据缓存  | 
            |
| 197 | 
                - # set_group_users_info(group) if group_user_created else get_group_users_info(group_id, user_id)  | 
            |
| 198 | 
                -  | 
            |
| 199 | 181 | 
                if photo:  | 
            
| 200 | 182 | 
                # 写 PhotosInfo 表  | 
            
| 201 | 
                - _, extension = os.path.splitext(photo.name)  | 
            |
| 202 | 
                - extension = extension or 'jpeg'  | 
            |
| 203 | 
                -  | 
            |
| 204 | 
                -        m_photo_path = 'photo/{uuid}{extension}'.format(uuid=shortuuid.uuid(), extension=extension)
               | 
            |
| 205 | 
                -  | 
            |
| 206 | 
                - if default_storage.exists(m_photo_path):  | 
            |
| 207 | 
                - default_storage.delete(m_photo_path)  | 
            |
| 208 | 
                - default_storage.save(m_photo_path, photo)  | 
            |
| 209 | 
                -  | 
            |
| 210 | 
                -        p_photo_path = 'photo/{uuid}{extension}'.format(uuid=shortuuid.uuid(), extension=extension)
               | 
            |
| 183 | 
                + m_photo_path, ext = file_save(photo, prefix='photo', ext='jpeg')  | 
            |
| 184 | 
                +        p_photo_path = 'photo/{}{}'.format(shortuuid.uuid(), ext)
               | 
            |
| 211 | 185 | 
                watermark_wrap(  | 
            
| 212 | 186 | 
                             os.path.join(settings.MEDIA_ROOT, m_photo_path).replace('\\', '/'),
               | 
            
| 213 | 187 | 
                settings.WATERMARK_LOGO,  | 
            
                @@ -348,14 +322,7 @@ def lensman_origin_photo_upload_api(request):  | 
            ||
| 348 | 322 | 
                 | 
            
| 349 | 323 | 
                if photo:  | 
            
| 350 | 324 | 
                # 写 PhotosInfo 表  | 
            
| 351 | 
                - _, extension = os.path.splitext(photo.name)  | 
            |
| 352 | 
                - extension = extension or 'jpeg'  | 
            |
| 353 | 
                -  | 
            |
| 354 | 
                -        r_photo_path = 'photo/{uuid}{extension}'.format(uuid=shortuuid.uuid(), extension=extension)
               | 
            |
| 355 | 
                -  | 
            |
| 356 | 
                - if default_storage.exists(r_photo_path):  | 
            |
| 357 | 
                - default_storage.delete(r_photo_path)  | 
            |
| 358 | 
                - default_storage.save(r_photo_path, photo)  | 
            |
| 325 | 
                + r_photo_path, ext = file_save(photo, prefix='photo', ext='jpeg')  | 
            |
| 359 | 326 | 
                 | 
            
| 360 | 327 | 
                PhotosInfo.objects.filter(  | 
            
| 361 | 328 | 
                lensman_id=lensman_id,  | 
            
                @@ -47,6 +47,9 @@ class GroupInfo(CreateUpdateMixin):  | 
            ||
| 47 | 47 | 
                gather_lon = models.FloatField(_(u'gather_lon'), blank=True, null=True, help_text=_(u'旅游团集合经度'))  | 
            
| 48 | 48 | 
                gather_lat = models.FloatField(_(u'gather_lat'), blank=True, null=True, help_text=_(u'旅游团集合纬度'))  | 
            
| 49 | 49 | 
                 | 
            
| 50 | 
                + attentions_path = models.CharField(_(u'attentions_path'), max_length=255, blank=True, null=True, help_text=u'注意事项照片存放路径')  | 
            |
| 51 | 
                + schedules_path = models.CharField(_(u'schedules_path'), max_length=255, blank=True, null=True, help_text=u'行程安排照片存放路径')  | 
            |
| 52 | 
                +  | 
            |
| 50 | 53 | 
                class Meta:  | 
            
| 51 | 54 | 
                verbose_name = _(u'groupinfo')  | 
            
| 52 | 55 | 
                verbose_name_plural = _(u'groupinfo')  | 
            
                @@ -59,6 +62,14 @@ class GroupInfo(CreateUpdateMixin):  | 
            ||
| 59 | 62 | 
                return img_url(self.group_avatar)  | 
            
| 60 | 63 | 
                 | 
            
| 61 | 64 | 
                @property  | 
            
| 65 | 
                + def group_attentions_url(self):  | 
            |
| 66 | 
                + return img_url(self.attentions_path)  | 
            |
| 67 | 
                +  | 
            |
| 68 | 
                + @property  | 
            |
| 69 | 
                + def group_schedules_url(self):  | 
            |
| 70 | 
                + return img_url(self.schedules_path)  | 
            |
| 71 | 
                +  | 
            |
| 72 | 
                + @property  | 
            |
| 62 | 73 | 
                def data(self):  | 
            
| 63 | 74 | 
                         return {
               | 
            
| 64 | 75 | 
                'group_id': self.group_id,  | 
            
                @@ -79,8 +90,10 @@ class GroupInfo(CreateUpdateMixin):  | 
            ||
| 79 | 90 | 
                'gather_lon': self.gather_lon,  | 
            
| 80 | 91 | 
                'gather_lat': self.gather_lat,  | 
            
| 81 | 92 | 
                'created_at': tc.remove_microsecond(self.created_at),  | 
            
| 82 | 
                - # TODO: tour guide upload banners, include travel route, matters need attention, and so on  | 
            |
| 83 | 
                - 'banners': [],  | 
            |
| 93 | 
                +            'banners': {
               | 
            |
| 94 | 
                + 'attentions': self.group_attentions_url,  | 
            |
| 95 | 
                + 'schedules': self.group_schedules_url,  | 
            |
| 96 | 
                + },  | 
            |
| 84 | 97 | 
                }  | 
            
| 85 | 98 | 
                 | 
            
| 86 | 99 | 
                def users(self, admin=True, user_id=None):  | 
            
                @@ -3,12 +3,10 @@  | 
            ||
| 3 | 3 | 
                from __future__ import division  | 
            
| 4 | 4 | 
                 | 
            
| 5 | 5 | 
                import json  | 
            
| 6 | 
                -import os  | 
            |
| 7 | 6 | 
                 | 
            
| 8 | 7 | 
                import shortuuid  | 
            
| 9 | 8 | 
                from curtail_uuid import CurtailUUID  | 
            
| 10 | 9 | 
                from django.conf import settings  | 
            
| 11 | 
                -from django.core.files.storage import default_storage  | 
            |
| 12 | 10 | 
                from django.core.serializers.json import DjangoJSONEncoder  | 
            
| 13 | 11 | 
                from logit import logit  | 
            
| 14 | 12 | 
                from TimeConvert import TimeConvert as tc  | 
            
                @@ -21,6 +19,7 @@ from utils.redis.rgroup import get_group_info, get_group_users_info, set_group_i  | 
            ||
| 21 | 19 | 
                from utils.redis.rkeys import (TOUR_GUIDE_GROUP_CUR_GATHER_INFO, TOUR_GUIDE_GROUP_CUR_SESSION,  | 
            
| 22 | 20 | 
                TOUR_GUIDE_GROUP_USER_BELONG)  | 
            
| 23 | 21 | 
                from utils.redis.rtourguide import get_tour_guide_own_group, set_tour_guide_own_group  | 
            
| 22 | 
                +from utils.storage_utils import file_save  | 
            |
| 24 | 23 | 
                 | 
            
| 25 | 24 | 
                 | 
            
| 26 | 25 | 
                r = settings.REDIS_CACHE  | 
            
                @@ -146,6 +145,9 @@ def tg_group_update_api(request):  | 
            ||
| 146 | 145 | 
                     ended_at = tc.utc_string_to_utc_datetime(request.POST.get('ended_at', ''))  # UTC, %Y-%m-%dT%H:%M:%SZ
               | 
            
| 147 | 146 | 
                     total_persons = request.POST.get('total_persons', '')
               | 
            
| 148 | 147 | 
                 | 
            
| 148 | 
                +    attentions = request.FILES.get('attentions', '')
               | 
            |
| 149 | 
                +    schedules = request.FILES.get('schedules', '')
               | 
            |
| 150 | 
                +  | 
            |
| 149 | 151 | 
                # 群组校验  | 
            
| 150 | 152 | 
                try:  | 
            
| 151 | 153 | 
                group = GroupInfo.objects.get(group_id=group_id)  | 
            
                @@ -164,19 +166,21 @@ def tg_group_update_api(request):  | 
            ||
| 164 | 166 | 
                group.group_desc = group_desc  | 
            
| 165 | 167 | 
                # 群组头像更新  | 
            
| 166 | 168 | 
                if group_avatar:  | 
            
| 167 | 
                - _, extension = os.path.splitext(group_avatar.name)  | 
            |
| 168 | 
                -        group_avatar_path = 'group/{uuid}_{extension}'.format(uuid=shortuuid.uuid(), extension=extension)
               | 
            |
| 169 | 
                - if default_storage.exists(group_avatar_path):  | 
            |
| 170 | 
                - default_storage.delete(group_avatar_path)  | 
            |
| 171 | 
                - default_storage.save(group_avatar_path, group_avatar)  | 
            |
| 172 | 
                - group.group_avatar = group_avatar_path  | 
            |
| 169 | 
                + group.group_avatar = file_save(group_avatar, prefix='group', ext='jpeg')[0]  | 
            |
| 173 | 170 | 
                # 起止时间更新  | 
            
| 174 | 171 | 
                if started_at:  | 
            
| 175 | 172 | 
                group.started_at = started_at  | 
            
| 176 | 173 | 
                if ended_at:  | 
            
| 177 | 174 | 
                group.ended_at = ended_at  | 
            
| 175 | 
                + # 旅行团总人数更新  | 
            |
| 178 | 176 | 
                if total_persons:  | 
            
| 179 | 177 | 
                group.total_persons = total_persons  | 
            
| 178 | 
                + # 注意事项更新  | 
            |
| 179 | 
                + if attentions:  | 
            |
| 180 | 
                + group.attentions = file_save(attentions, prefix='tour', ext='jpeg')[0]  | 
            |
| 181 | 
                + # 行程安排更新  | 
            |
| 182 | 
                + if schedules:  | 
            |
| 183 | 
                + group.schedules = file_save(schedules, prefix='tour', ext='jpeg')[0]  | 
            |
| 180 | 184 | 
                group.save()  | 
            
| 181 | 185 | 
                 | 
            
| 182 | 186 | 
                # Redis 群组数据缓存更新  | 
            
                @@ -5,10 +5,8 @@ from __future__ import division  | 
            ||
| 5 | 5 | 
                import os  | 
            
| 6 | 6 | 
                import random  | 
            
| 7 | 7 | 
                 | 
            
| 8 | 
                -import shortuuid  | 
            |
| 9 | 8 | 
                from curtail_uuid import CurtailUUID  | 
            
| 10 | 9 | 
                from django.conf import settings  | 
            
| 11 | 
                -from django.core.files.storage import default_storage  | 
            |
| 12 | 10 | 
                from django.db import connection, transaction  | 
            
| 13 | 11 | 
                from logit import logit  | 
            
| 14 | 12 | 
                from rest_framework import viewsets  | 
            
                @@ -32,6 +30,7 @@ from utils.redis.rkeys import (GROUP_LAST_PHOTO_PK, GROUP_PHOTO_WATCHER_SET, GRO  | 
            ||
| 32 | 30 | 
                from utils.redis.rorder import get_lensman_order_record  | 
            
| 33 | 31 | 
                from utils.redis.rprice import get_lensman_price_fixed  | 
            
| 34 | 32 | 
                from utils.sql.raw import PAI2_HOME_API  | 
            
| 33 | 
                +from utils.storage_utils import file_save  | 
            |
| 35 | 34 | 
                from utils.thumbnail_utils import make_thumbnail  | 
            
| 36 | 35 | 
                from utils.time_utils import origin_expired_stamps  | 
            
| 37 | 36 | 
                from utils.url_utils import img_url, share_url  | 
            
                @@ -135,12 +134,7 @@ def group_update_api(request):  | 
            ||
| 135 | 134 | 
                group.group_desc = group_desc  | 
            
| 136 | 135 | 
                # 群组头像更新  | 
            
| 137 | 136 | 
                if group_avatar:  | 
            
| 138 | 
                - _, extension = os.path.splitext(group_avatar.name)  | 
            |
| 139 | 
                -        group_avatar_path = 'group/{uuid}_{extension}'.format(uuid=shortuuid.uuid(), extension=extension)
               | 
            |
| 140 | 
                - if default_storage.exists(group_avatar_path):  | 
            |
| 141 | 
                - default_storage.delete(group_avatar_path)  | 
            |
| 142 | 
                - default_storage.save(group_avatar_path, group_avatar)  | 
            |
| 143 | 
                - group.group_avatar = group_avatar_path  | 
            |
| 137 | 
                + group.group_avatar = file_save(group_avatar, prefix='group', ext='jpeg')[0]  | 
            |
| 144 | 138 | 
                group.save()  | 
            
| 145 | 139 | 
                 | 
            
| 146 | 140 | 
                # Redis 群组数据缓存更新  | 
            
                @@ -260,18 +254,10 @@ def flyimg_upload_api(request):  | 
            ||
| 260 | 254 | 
                return response(GroupUserStatusCode.GROUP_USER_NOT_FOUND)  | 
            
| 261 | 255 | 
                 | 
            
| 262 | 256 | 
                if photo:  | 
            
| 263 | 
                -        photo_path = 'fly/{uuid}{extension}'.format(uuid=shortuuid.uuid(), extension=os.path.splitext(photo.name)[1] or 'jpeg')
               | 
            |
| 257 | 
                + photo_path, ext = file_save(photo, prefix='fly', ext='jpeg')  | 
            |
| 264 | 258 | 
                         photo_thumbnail_path = photo_path.replace('.', '_thumbnail.')
               | 
            
| 265 | 259 | 
                         photo_thumbnail2_path = photo_path.replace('.', '_thumbnail2.')
               | 
            
| 266 | 260 | 
                 | 
            
| 267 | 
                - if default_storage.exists(photo_path):  | 
            |
| 268 | 
                - default_storage.delete(photo_path)  | 
            |
| 269 | 
                - default_storage.save(photo_path, photo)  | 
            |
| 270 | 
                -  | 
            |
| 271 | 
                - # if default_storage.exists(photo_thumbnail_path):  | 
            |
| 272 | 
                - # default_storage.delete(photo_thumbnail_path)  | 
            |
| 273 | 
                - # default_storage.save(photo_thumbnail_path, photo)  | 
            |
| 274 | 
                -  | 
            |
| 275 | 261 | 
                # 群组照片缩略图生成  | 
            
| 276 | 262 | 
                # 双列: 540, 40-50K  | 
            
| 277 | 263 | 
                photo_w, photo_h, photo_thumbnail_w, photo_thumbnail_h = make_thumbnail(  | 
            
                @@ -5,7 +5,6 @@ import os  | 
            ||
| 5 | 5 | 
                import shortuuid  | 
            
| 6 | 6 | 
                from curtail_uuid import CurtailUUID  | 
            
| 7 | 7 | 
                from django.conf import settings  | 
            
| 8 | 
                -from django.core.files.storage import default_storage  | 
            |
| 9 | 8 | 
                from django.db import transaction  | 
            
| 10 | 9 | 
                from django.shortcuts import render  | 
            
| 11 | 10 | 
                from django_q.tasks import async  | 
            
                @@ -24,6 +23,7 @@ from utils.redis.rgroup import get_group_info, set_group_info, set_group_users_i  | 
            ||
| 24 | 23 | 
                from utils.redis.rkeys import (GROUP_LAST_PHOTO_PK, GROUP_USERS_DELETED_SET, GROUP_USERS_PASSED_SET,  | 
            
| 25 | 24 | 
                GROUP_USERS_QUIT_SET, GROUP_USERS_REFUSED_SET, UUID_LIST)  | 
            
| 26 | 25 | 
                from utils.redis.ruuid import generate_uuids, update_uuids  | 
            
| 26 | 
                +from utils.storage_utils import file_save  | 
            |
| 27 | 27 | 
                from utils.thumbnail_utils import make_thumbnail  | 
            
| 28 | 28 | 
                from utils.watermark_utils import watermark_wrap  | 
            
| 29 | 29 | 
                 | 
            
                @@ -93,18 +93,9 @@ def upload_photo(request):  | 
            ||
| 93 | 93 | 
                except LensmanInfo.DoesNotExist:  | 
            
| 94 | 94 | 
                return response(LensmanStatusCode.LENSMAN_NOT_FOUND)  | 
            
| 95 | 95 | 
                 | 
            
| 96 | 
                - # photo_id = curtailUUID(PhotosInfo, 'photo_id')  | 
            |
| 96 | 
                + m_photo_path, ext = file_save(photo, prefix='photo', ext='jpeg')  | 
            |
| 97 | 97 | 
                 | 
            
| 98 | 
                - _, extension = os.path.splitext(photo.name)  | 
            |
| 99 | 
                - extension = extension or 'jpeg'  | 
            |
| 100 | 
                -  | 
            |
| 101 | 
                -    m_photo_path = 'photo/{uuid}{extension}'.format(uuid=shortuuid.uuid(), extension=extension)
               | 
            |
| 102 | 
                -  | 
            |
| 103 | 
                - if default_storage.exists(m_photo_path):  | 
            |
| 104 | 
                - default_storage.delete(m_photo_path)  | 
            |
| 105 | 
                - default_storage.save(m_photo_path, photo)  | 
            |
| 106 | 
                -  | 
            |
| 107 | 
                -    p_photo_path = 'photo/{uuid}{extension}'.format(uuid=shortuuid.uuid(), extension=extension)
               | 
            |
| 98 | 
                +    p_photo_path = 'photo/{}{}'.format(shortuuid.uuid(), ext)
               | 
            |
| 108 | 99 | 
                watermark_wrap(  | 
            
| 109 | 100 | 
                         os.path.join(settings.MEDIA_ROOT, m_photo_path).replace('\\', '/'),
               | 
            
| 110 | 101 | 
                settings.WATERMARK_LOGO,  | 
            
                @@ -0,0 +1,15 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +import os  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +import shortuuid  | 
            |
| 6 | 
                +from django.core.files.storage import default_storage  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                +def file_save(file_, prefix='img', ext='jpeg'):  | 
            |
| 10 | 
                + ext = os.path.splitext(file_.name)[-1] or ext  | 
            |
| 11 | 
                +    path = '{}/{}{}'.format(prefix, shortuuid.uuid(), ext)
               | 
            |
| 12 | 
                + if default_storage.exists(path):  | 
            |
| 13 | 
                + default_storage.delete(path)  | 
            |
| 14 | 
                + default_storage.save(path, file_)  | 
            |
| 15 | 
                + return path, ext  |